<?php
class XA_Image {

	public $image;
	protected $file;
	
	public $width, $height;
	
	public $type;
	public $save_proportions = true;
	public $errors = array();
	
	
	public function create($width, $height, $bgcolor = null, $alpha = 0) {
		$this->image = imagecreatetruecolor($width, $height);
		imagealphablending($this->image, true);
		imagesavealpha($this->image, true);
		if ($bgcolor) {
			imagefill($this->image, 0, 0, $this->prepareColor($bgcolor, $alpha));
		}
		$this->width = $width;
		$this->height = $height;
	}
	
	
	
	public function open($file, $type = null) {
		$info = getimagesize($file);
		$this->width = $info[0];
		$this->height = $info[1];
		$this->file = $file;
		if ($type) {
			$this->type = $type;
		} else {
			$this->type = $info['mime'];
		}

		switch ($this->type) {
			case ('image/png'):
				$this->image = imagecreatefrompng($file);
				imagealphablending($this->image, true);
				imagesavealpha($this->image, true);
				$this->ext = 'png';
				break;
			default:
				$this->image = imagecreatefromjpeg($file);
				$this->ext = 'jpg';
				break;
		}
	}


	public function resize($width = null, $height = null) {
		$format = $this->width / $this->height;
		$new_width = $width;
		$new_height = $height;
		if (!$new_width) {
			$new_width = intval($new_height * $format);
		}
		if (!$new_height) {
			$new_height = intval($new_width / $format);
		}
		$new_image = imagecreatetruecolor($new_width, $new_height);
		imagealphablending($new_image, true);
		imagesavealpha($new_image, true);
		imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $new_width, $new_height, $this->width, $this->height);
		$this->width = $new_width;
		$this->height = $new_height;
		$this->image = $new_image;
	}


	public function fill($width = null, $height = null) {
		if ($this->width - $width < $this->height - $height) {
			$new_width = $width;
			$new_height = intval(($width / $this->width) * $this->height);
			$x = 0;
			$y = intval(($new_height - $height) / 2);
		} else {
			$new_height = $height;
			$new_width = intval(($height / $this->height) * $this->width);
			$x = intval(($new_width - $width) / 2);
			$y = 0;
		}

		$this->resize($new_width, $new_height);
		$this->crop($x, $y, $width, $height);
	}


	public function fit($width = null, $height = null) {
		$format = $this->width / $this->height;
		$new_width = ($width && ($this->width > intval($width)) ? intval($width) : $this->width);
		$new_height = intval($new_width / $format);
		if ($height) {
			$new_height = ($new_height > intval($height)?intval($height):$new_height);
			$new_width = intval($new_height * $format);
		}
		$new_image = imagecreatetruecolor($new_width, $new_height);
		imagealphablending($new_image, true);
		imagefill($new_image, 0, 0, $this->prepareColor('000000', 127));
		imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $new_width, $new_height, $this->width, $this->height);
		imagesavealpha($new_image, true);
		$this->width = $new_width;
		$this->height = $new_height;
		$this->image = $new_image;
	}


	public function crop($x, $y, $width, $height) {
		$new_image = imagecreatetruecolor($width, $height);
		imagealphablending($new_image, true);
		imagefill($new_image, 0, 0, $this->prepareColor('ff0000', 127));
		imagecopyresampled($new_image, $this->image, 0, 0, $x, $y, $width, $height, $width, $height);
		imagesavealpha($new_image, true);
		$this->width = $width;
		$this->height = $height;
		$this->image = $new_image;
	}


	public function paste($image_object, $x, $y) {
		return imagecopy($this->image, $image_object->image, $x, $y, 0, 0, $image_object->width, $image_object->height);
	}


	public function write($size, $x, $y, $color, $fontfile, $text) {
		return imagefttext($this->image, $size, 0, $x, $y, $this->prepareColor($color), APP_PATH.'fonts/'.$fontfile, $text);
	}
	
	
	public function prepareColor($color, $alpha = 0) {
		list($red, $green, $blue) = str_split($color, 2);
		return imagecolorexactalpha($this->image, hexdec($red), hexdec($green), hexdec($blue), $alpha);
	}


	public function save($quality = 75) {
		$this->output($this->file, $quality);
	}


	public function output($file = null, $quality = 75) {
		switch ($this->type) {
			case 'image/png':
				header('Content-Type: image/png');
				imagepng($this->image, $file, 9);
				break;
			default:
				header('Content-Type: image/jpeg');
				imagejpeg($this->image, $file, $quality);
				break;
		}
	}
}
